#!/usr/bin/env node

/**
 * 田小檬时间服务器 MCP
 * 一个简单的 MCP 服务，用于获取当前系统时间
 */

import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import {
  CallToolRequestSchema,
  ErrorCode,
  ListToolsRequestSchema,
  McpError,
} from '@modelcontextprotocol/sdk/types.js';

/**
 * 时间格式化工具类
 */
class TimeFormatter {
  /**
   * 获取当前时间的详细信息
   * @param {string} format - 时间格式类型
   * @returns {Object} 时间信息对象
   */
  static getCurrentTime(format = 'iso') {
    const now = new Date();
    const timestamp = now.getTime();
    const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
    const timezoneOffset = this.getTimezoneOffset(now);

    let formattedTime;
    switch (format.toLowerCase()) {
      case 'timestamp':
        formattedTime = timestamp;
        break;
      case 'local':
        formattedTime = now.toLocaleString();
        break;
      case 'utc':
        formattedTime = now.toUTCString();
        break;
      case 'iso':
      default:
        formattedTime = now.toISOString();
        break;
    }

    return {
      current_time: formattedTime,
      timestamp: timestamp,
      timezone: timezone,
      timezone_offset: timezoneOffset
    };
  }

  /**
   * 获取时间戳
   * @param {string} unit - 时间戳单位（milliseconds 或 seconds）
   * @returns {Object} 时间戳信息
   */
  static getTimestamp(unit = 'milliseconds') {
    const now = new Date();
    let timestamp = now.getTime();
    
    if (unit.toLowerCase() === 'seconds') {
      timestamp = Math.floor(timestamp / 1000);
    }

    return {
      timestamp: timestamp,
      unit: unit
    };
  }

  /**
   * 格式化时间戳
   * @param {number} timestamp - Unix 时间戳（毫秒）
   * @param {string} format - 输出格式
   * @param {string} pattern - 自定义格式模式
   * @returns {Object} 格式化后的时间信息
   */
  static formatTime(timestamp, format = 'iso', pattern = null) {
    const date = new Date(timestamp);
    let formattedTime;

    switch (format.toLowerCase()) {
      case 'local':
        formattedTime = date.toLocaleString();
        break;
      case 'utc':
        formattedTime = date.toUTCString();
        break;
      case 'custom':
        if (pattern) {
          formattedTime = this.customFormat(date, pattern);
        } else {
          formattedTime = date.toISOString();
        }
        break;
      case 'iso':
      default:
        formattedTime = date.toISOString();
        break;
    }

    return {
      formatted_time: formattedTime,
      original_timestamp: timestamp,
      format_used: format
    };
  }

  /**
   * 自定义时间格式化
   * @param {Date} date - 日期对象
   * @param {string} pattern - 格式模式
   * @returns {string} 格式化后的时间字符串
   */
  static customFormat(date, pattern) {
    const year = date.getFullYear();
    const month = String(date.getMonth() + 1).padStart(2, '0');
    const day = String(date.getDate()).padStart(2, '0');
    const hours = String(date.getHours()).padStart(2, '0');
    const minutes = String(date.getMinutes()).padStart(2, '0');
    const seconds = String(date.getSeconds()).padStart(2, '0');
    const milliseconds = String(date.getMilliseconds()).padStart(3, '0');

    return pattern
      .replace(/YYYY/g, year)
      .replace(/MM/g, month)
      .replace(/DD/g, day)
      .replace(/HH/g, hours)
      .replace(/mm/g, minutes)
      .replace(/ss/g, seconds)
      .replace(/SSS/g, milliseconds);
  }

  /**
   * 获取时区偏移量
   * @param {Date} date - 日期对象
   * @returns {string} 时区偏移量字符串
   */
  static getTimezoneOffset(date) {
    const offset = -date.getTimezoneOffset();
    const hours = Math.floor(Math.abs(offset) / 60);
    const minutes = Math.abs(offset) % 60;
    const sign = offset >= 0 ? '+' : '-';
    return `${sign}${String(hours).padStart(2, '0')}:${String(minutes).padStart(2, '0')}`;
  }
}

/**
 * 创建并配置 MCP 服务器
 */
class TimeServer {
  constructor() {
    this.server = new Server(
      {
        name: 'xiaomeng-time-server',
        version: '1.0.0',
      },
      {
        capabilities: {
          tools: {},
        },
      }
    );

    this.setupToolHandlers();
    this.setupErrorHandling();
  }

  /**
   * 设置工具处理器
   */
  setupToolHandlers() {
    // 列出可用工具
    this.server.setRequestHandler(ListToolsRequestSchema, async () => {
      return {
        tools: [
          {
            name: 'get_current_time',
            description: '获取当前系统时间的详细信息',
            inputSchema: {
              type: 'object',
              properties: {
                format: {
                  type: 'string',
                  description: '时间格式：iso（默认）、timestamp、local、utc',
                  enum: ['iso', 'timestamp', 'local', 'utc'],
                  default: 'iso'
                }
              }
            }
          },
          {
            name: 'get_timestamp',
            description: '获取当前 Unix 时间戳',
            inputSchema: {
              type: 'object',
              properties: {
                unit: {
                  type: 'string',
                  description: '时间戳单位：milliseconds（默认）、seconds',
                  enum: ['milliseconds', 'seconds'],
                  default: 'milliseconds'
                }
              }
            }
          },
          {
            name: 'format_time',
            description: '将时间戳格式化为指定格式',
            inputSchema: {
              type: 'object',
              properties: {
                timestamp: {
                  type: 'number',
                  description: 'Unix 时间戳（毫秒）'
                },
                format: {
                  type: 'string',
                  description: '输出格式：iso（默认）、local、utc、custom',
                  enum: ['iso', 'local', 'utc', 'custom'],
                  default: 'iso'
                },
                pattern: {
                  type: 'string',
                  description: '自定义格式模式，如 "YYYY-MM-DD HH:mm:ss"（仅在 format 为 custom 时使用）'
                }
              },
              required: ['timestamp']
            }
          }
        ]
      };
    });

    // 处理工具调用
    this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
      const { name, arguments: args } = request.params;

      try {
        switch (name) {
          case 'get_current_time':
            return {
              content: [
                {
                  type: 'text',
                  text: JSON.stringify(TimeFormatter.getCurrentTime(args?.format), null, 2)
                }
              ]
            };

          case 'get_timestamp':
            return {
              content: [
                {
                  type: 'text',
                  text: JSON.stringify(TimeFormatter.getTimestamp(args?.unit), null, 2)
                }
              ]
            };

          case 'format_time':
            if (!args?.timestamp) {
              throw new McpError(
                ErrorCode.InvalidParams,
                '缺少必需参数：timestamp'
              );
            }
            return {
              content: [
                {
                  type: 'text',
                  text: JSON.stringify(
                    TimeFormatter.formatTime(args.timestamp, args?.format, args?.pattern),
                    null,
                    2
                  )
                }
              ]
            };

          default:
            throw new McpError(
              ErrorCode.MethodNotFound,
              `未知工具：${name}`
            );
        }
      } catch (error) {
        if (error instanceof McpError) {
          throw error;
        }
        throw new McpError(
          ErrorCode.InternalError,
          `工具执行错误：${error.message}`
        );
      }
    });
  }

  /**
   * 设置错误处理
   */
  setupErrorHandling() {
    this.server.onerror = (error) => {
      console.error('[MCP Error]', error);
    };

    process.on('SIGINT', async () => {
      await this.server.close();
      process.exit(0);
    });
  }

  /**
   * 启动服务器
   */
  async start() {
    const transport = new StdioServerTransport();
    await this.server.connect(transport);
    console.error('田小檬时间服务器 MCP 已启动');
  }
}

/**
 * 主函数
 */
async function main() {
  try {
    const timeServer = new TimeServer();
    await timeServer.start();
  } catch (error) {
    console.error('启动服务器失败:', error);
    process.exit(1);
  }
}

// 启动服务
if (process.argv[1] && (import.meta.url === `file://${process.argv[1]}` || import.meta.url.includes('index.js'))) {
  main().catch(console.error);
}

export { TimeServer, TimeFormatter };